package soccerscope.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Implements a list of all starting scenes of play modes.
 * 
 * @author benjaboe
 * 
 */
public class ScenePlayModeList
    implements Serializable {

  private static final long                           serialVersionUID = 5456351238465384299L;

  /** the list of the modes. */
  private ArrayList<ScenePlayModeListItem>            playModeList;

  /** list of the observer - should be informed when list changed. */
  private static ArrayList<ScenePlayModeListObserver> observers        = new ArrayList();

  /**
   * Creates a new list of all starting scenes of play modes.
   */
  public ScenePlayModeList() {

    this.playModeList = new ArrayList<ScenePlayModeListItem>();
  }

  /**
   * Adds a scene to the list of scenes with beginning play modes
   * 
   * @param scene
   *          the scene where a play mode starts
   * @param cycle
   *          the cycle number which is shown by the SoccerScope
   * @param mode
   *          the new play mode
   */
  public void addSceneMode(int scene,
      int cycle,
      PlayMode mode) {

    if (this.playModeList.isEmpty() || !this.playModeList.get(
        this.playModeList.size() - 1).getMode().equals(mode)) {
      ScenePlayModeListItem item = new ScenePlayModeListItem(scene, cycle, mode);
      this.playModeList.add(item);

      Iterator<ScenePlayModeListObserver> it = ScenePlayModeList.observers
          .iterator();
      while (it.hasNext()) {
        it.next().newScenePlayModeAdded(item);
      }
    }
  }

  /**
   * Should be called when the whole ScenePlayModeList has changed. Called after
   * loading
   * 
   */
  public static void allChanged() {

    Iterator<ScenePlayModeListObserver> it = ScenePlayModeList.observers
        .iterator();
    while (it.hasNext()) {
      it.next().allChanged();
    }

  }

  /**
   * Returns the list of scenes where a new play mode starts.
   * 
   * @return the list of scenes where a new play mode starts
   */
  public List<ScenePlayModeListItem> getAllScenePlayModes() {

    return this.playModeList;
  }

  /**
   * Returns a list of scenes where a specified play moe starts.
   * 
   * @param mode
   *          the mode
   * @return list of the scenes which start with the play mode
   */
  public List<ScenePlayModeListItem> getScenesByPlayMode(PlayMode mode) {

    ArrayList<ScenePlayModeListItem> items = new ArrayList();
    Iterator<ScenePlayModeListItem> it = this.playModeList.iterator();
    while (it.hasNext()) {
      ScenePlayModeListItem item = it.next();
      if (item.getMode().equals(mode)) {
        items.add(item);
      }
    }
    return items;
  }

  /**
   * Returns the list of all occurend play modes of the game.
   * 
   * @return the list of all occurend play modes of the game
   */
  public List<PlayMode> getOccuredModes() {

    ArrayList<PlayMode> modes = new ArrayList();
    Iterator<ScenePlayModeListItem> it = this.playModeList.iterator();
    while (it.hasNext()) {
      ScenePlayModeListItem item = it.next();
      if (!modes.contains(item.getMode())) {
        modes.add(item.getMode());
      }
    }
    return modes;
  }

  /**
   * Adds a observer to the observer list.
   * 
   * @param observer
   *          the new observer
   */
  public void addObserver(ScenePlayModeListObserver observer) {

    if (!ScenePlayModeList.observers.contains(observer)) {
      ScenePlayModeList.observers.add(observer);
    }
  }

  /**
   * removes a observer from the observer list.
   * 
   * @param observer
   *          the observer to remove
   */
  public void removeObserver(ScenePlayModeListObserver observer) {

    ScenePlayModeList.observers.remove(observer);
  }
}
